package _general.geometry;

import java.util.ArrayList;
import _general.geometry.Edge;

public class EdgeList<E> extends ArrayList<Edge> {

	/**
	 * 
	 */
	private static final long serialVersionUID = -4915861610872340510L;

	public EdgeList() {
		super();
		
	}
	
	public void swap(Edge edge1, Edge edge2) {
		 if(!this.contains(edge1) || !this.contains(edge2))
	            return;

	        int pos1 = this.indexOf(edge1);
	        int pos2 = this.indexOf(edge2);

	        //System.out.println("swap postions "+pos1+", "+pos2);
	        Edge tmp = this.get(pos1);
	        this.set(pos1, edge2);
	        this.set(pos2, tmp);
	}

	
	public Edge getSuccessor(Edge element) {
		
		if (element.equals(this.get(this.size() - 1 )))
			return null;
		
		
		for (int i = 0; i < this.size() - 1; i++) {
			if (element.equals(this.get(i))){
				//System.out.println("Successor:\t" + edgeList.get(i+1).getStart().getX() + "\t" + edgeList.get(i+1).getStart().getY());
				return(this.get(i+1));
			}
		}
		return null;
	}
	
	public Edge getPredecessor(Edge element) {
		
		if (element.equals(this.get(0)))
			return null;
		
		for (int i = 1; i < this.size(); i++) {
			if (element.equals(this.get(i))){
				//System.out.println("Predecessor:\t" + edgeList.get(i-1).getStart().getX() + "\t" + edgeList.get(i-1).getStart().getY());
				return(this.get(i-1));
			}
		}
		
		return null;
	}
	
	public void sortedAdd(Edge edge1) {
		
		//System.out.println ("Insert edge to list of active edges");
		
		if (this.size() == 0) {
			this.add(edge1);
			return;
		}
		
		Node insertNode = edge1.getStart();
		Node startNode, endNode;
		double det = 0;
		
		for(int i = 0; i < this.size(); i++) {
			startNode = this.get(i).getStart();
			endNode = this.get(i).getEnd();
			
//			System.out.println("Testing:");
//			System.out.println("insertNode:\t" + insertNode.getX() + "\t" + insertNode.getY());
//			System.out.println("startNode:\t" + startNode.getX() + "\t" + startNode.getY());
//			System.out.println("endNode:\t" + endNode.getX() + "\t" + endNode.getY());
			
			
			/*
			 * | startNode.getX()	startNode.getY()	1 |
			 * | endNode.getX()		endNode.getY()		1 |
			 * | insertNode.getX()	insertNode.getY()	1 |
			 */
			// ermittle Determinante von startNode, endNode und insertNode
			det = getDeterminant(startNode, endNode, insertNode);
			
			//System.out.println("Determinante: " + det);
			
			if (det > 0 ) {
				this.add(i, edge1);
				return;
			}
				  
		}
		
		//System.out.println("Insert edge at the end of the list");
		this.add(edge1);
		
		
	}

	private double getDeterminant(Point p1, Point p2, Point p3) {
		/*
		 * | p1.getX()	p1.getY()	1 |
		 * | p2.getX()	p2.getY()	1 |
		 * | p3.getX()	p3.getY()	1 |
		 */
		double det = p1.getX() * p2.getY() + 
			  		p1.getY() * p3.getX() + 
			  		p2.getX() * p3.getY() -
			  		p2.getY() * p3.getX() -
			  		p1.getX() * p3.getY() -
			  		p1.getY() * p2.getX();
		
		return det;
	}
}
